const http=require('http')
const WebSocket = require('ws');
const ws = new WebSocket.Server({ port: 8001 });

// 房间列表[{id,name,ai}]
let rooms = []
// 所有进入房间的对象[{username,roomId,ws}]
let clients = []
// 所有连接的对象包括大厅和房间中的[ws]
let allUser = []
ws.on('connection', ws => {
    console.log('server connection');
    // 连接成功,将用户加入所有用户数组
    if (!allUser.some(item => item === ws)) allUser.push(ws)
    ws.on('message', msg => {
        const res = JSON.parse(msg)
        if (res.type === 'enterroom') {
            // 进入房间
            if (!clients.some(item => item.ws === ws)) enterRoom(res.data.roomId, res.data.username, ws)
        } else if (res.type === 'usermsg') {
            // 用户发送消息
            userSendMsg(ws, res)
        } else if (res.type === 'leaveroom') {
            // 用户离开房间
            leaveRoom(ws)
        } else if (res.type === 'newroom') {
            const id = Math.max(...rooms.map(item => item.id),0) + 1
            // 新建房间
            rooms.push({
                id,
                name: res.data.roomName,
                ai: res.data.isAi
            })
            // 用户进入这个房间
            enterRoom(id, res.data.username, ws)
            // 给所有用户发送新的房间列表信息
            allUser.forEach(item => {
                sendRoomList(item)
            })
        }
        console.log('server receive msg：', res);
    });
    ws.on('close', () => {
        console.log('客户端断开连接');
        leaveRoom(ws)
        // 移除用户
        allUser = allUser.filter(item => item !== ws)
    })
    ws.on('error', err => {
        console.log(err);
    })
    // 给用户发送房间列表信息
    sendRoomList(ws)
});

// 封装客户端进入房间方法
const enterRoom = (roomId, username, ws) => {
    // 用户第一次进入房间,加入数组
    clients.push({
        roomId,
        username,
        ws
    })
    // 判断房间是否是ai房
    const isAi = rooms.find(room => room.id === roomId).ai
    // 当前房间用户列表
    const userList = clients.filter(item => item.roomId === roomId).map(item => item.username)
    if(isAi) userList.push('AI菲菲')
    clients.forEach(item => {
        if (item.roomId === roomId) {
            if (item.ws !== ws) {
                // 给房间里其他用户发送系统消息
                item.ws.send(JSON.stringify({
                    type: 'server',
                    data: `${username}进入房间`,
                    time: new Date().toLocaleString()
                }))
            } else {
                // 给当前用户发送房间信息
                item.ws.send(JSON.stringify({
                    type: 'roominfo',
                    data: rooms.find(room => room.id === roomId)
                }))
            }
            // 给房间所有用户发送当前用户列表
            // 判断房间是否是ai房,如果是则加上一个ai用户
            item.ws.send(JSON.stringify({
                type: 'userslist',
                data: userList
            }))
        }
    })
}

// 封装客户端离开房间方法
const leaveRoom = ws => {
    // 获取离开的用户
    const leaveUser = clients.find(item => item.ws === ws)
    // 没有获取到说明用户没有进入房间,直接跳过
    if (!leaveUser) return
    // 数组移除客户端
    clients = clients.filter(item => item.ws !== ws)
    // 发送离开房间消息
    clients.forEach(item => {
        if (item.roomId === leaveUser.roomId) {
            // 发送系统消息
            item.ws.send(JSON.stringify({
                type: 'server',
                data: `${leaveUser.username}离开房间`,
                time: new Date().toLocaleString()
            }))
            // 发送当前用户列表
            item.ws.send(JSON.stringify({
                type: 'userslist',
                data: clients.filter(user => user.roomId === item.roomId).map(user => user.username)
            }))
        }
    })
    // 离开房间后,如果房间人数为0自动销毁
    if (!clients.some(item => item.roomId === leaveUser.roomId)) {
        rooms = rooms.filter(item => item.id !== leaveUser.roomId)
        // 给所有用户发送最新房间列表信息
        allUser.forEach(item => {
            sendRoomList(item)
        })
    }
}

// 封装发送房间列表方法
const sendRoomList = ws => {
    ws.send(JSON.stringify({
        type: 'room',
        data: rooms.map(room => ({
            ...room,
            count: clients.filter(user => user.roomId == room.id).length
        })),
        time: new Date().toLocaleString()
    }))
}

// 用户在房间中发送消息
const userSendMsg = (ws, res) => {
    // 找到发送消息的用户
    const sendUser = clients.find(item => item.ws === ws)
    // 判断是否是ai房间
    const isAi = rooms.find(room => room.id === sendUser.roomId).ai
    clients.forEach(item => {
        if (item.roomId === sendUser.roomId) {
            item.ws.send(JSON.stringify({
                ...res,
                name: sendUser.username,
                type: item.ws === ws ? 'selfmsg' : 'usermsg'
            }))
        }
    })
    // 如果是ai房间,让机器人说话
    if(isAi) aiAnswer(res.data, sendUser.roomId)
}

// 返回机器人的回答
const aiAnswer = (msg, airoomId) => {
    http.get('http://api.qingyunke.com/api.php?key=free&appid=0&msg=' + msg, response => {
        let result = ''
        response.on('data', (chunk) => {
            result += chunk;
        })
        response.on('end', () => {
            // 结束,发送消息给房间所有用户
            const answer = JSON.parse(result).content
            clients.forEach(item => {
                if(item.roomId === airoomId) {
                    item.ws.send(JSON.stringify({
                        data: answer,
                        time: new Date().toLocaleString(),
                        name: 'AI菲菲',
                        type: 'usermsg'
                    }))
                }
            })
        })
    }).on("error", (error) => {
        console.log("Error: " + error.message);
    })
}